package com.wjh.anyview.quartz.job;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wjh.anyview.dao.ExamMapper;
import com.wjh.anyview.dao.UserMapper;
import com.wjh.anyview.entity.po.Exam;
import com.wjh.anyview.entity.po.User;
import com.wjh.anyview.quartz.constant.LongConstant;
import com.wjh.anyview.service.ExamService;
import com.wjh.anyview.service.constant.ExamStatusConstant;
import com.wjh.anyview.util.SpringUtil;
import com.wjh.anyview.websocket.entity.bo.TopicMessage;
import com.wjh.anyview.websocket.entity.po.PreExamMessage;
import com.wjh.anyview.websocket.server.WebSocketResource;
import com.wjh.anyview.websocket.util.SecurityUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 正式开始考试的任务
 *
 * @author wjh
 * @date 2021/10/22 20:04
 * @Package com.wjh.anyview.quartz.job
 */
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
@Slf4j
@Component
public class BeginExamJob extends QuartzJobBean {

    private final StringRedisTemplate redisTemplate = SpringUtil.getBean("getRedisTemplate");

    private final ExamService examService = SpringUtil.getBean("examServiceImpl");

    private final ExamMapper examMapper = SpringUtil.getBean("examMapper");

    private final UserMapper userMapper = SpringUtil.getBean("userMapper");

    @Override
    protected void executeInternal(JobExecutionContext context) {
        String str = redisTemplate.opsForValue().get(WebSocketResource.PRE_EXAM_LIST);
        if (str != null) {
            //json转list集合
            List<PreExamMessage> preExamMessageList = JSON.parseArray(str, PreExamMessage.class);
            log.info("正在准备中的考试：" + preExamMessageList);

            //集合按照开始时间从小到大排序
            List<PreExamMessage> collect = preExamMessageList.stream()
                    .sorted(Comparator.comparing(PreExamMessage::getStartTime))
                    .collect(Collectors.toList());

            //有考试正在准备中
            if (collect.size() != 0) {
                PreExamMessage nowExam = collect.get(0);
                //该考试已经到时间了
                if (collect.get(0).getStartTime() < System.currentTimeMillis() / 1000) {
                    //删除已经开始的考试
                    collect.remove(0);
                    String json = JSON.toJSONString(collect);
                    redisTemplate.opsForValue().set(WebSocketResource.PRE_EXAM_LIST, json);
                    //获取需要考这个试的学号
                    List<String> numList = examService.listNumByExamId(nowExam.getExamId());
                    //更新数据库的考试状态--考试进行中
                    Exam exam = new Exam();
                    exam.setId(nowExam.getExamId());
                    exam.setStatus(ExamStatusConstant.IN_PROGRESS);
                    examMapper.updateById(exam);

                    //以当前毫秒时间戳作为redis中value的key
                    String key = String.valueOf(System.currentTimeMillis());
                    //redis中存放numList
                    String numListString = numList.toString();
                    String nums = numListString.substring(1, numListString.length() - 1);
                    redisTemplate.opsForValue().set(key, nums);
                    TopicMessage topicMessage = new TopicMessage();
                    topicMessage.setMessage("考试开始，请开始答题！");
                    topicMessage.setKey(key);

                    //向 TOPIC_EXAM 频道发送信息
                    redisTemplate.convertAndSend("TOPIC_EXAM", SecurityUtil.getTopicMessage(topicMessage));


                    //以当前毫秒时间戳作为redis中value的key
                    String keyTeacher = String.valueOf(System.currentTimeMillis() + 1L);
                    Exam examForDb = examMapper.selectById(nowExam.getExamId());
                    User user = userMapper.selectById(examForDb.getInvigilatorId());
                    //需要通知的教师的num
                    String numTeacherList = user.getNum();
                    redisTemplate.opsForValue().set(keyTeacher, numTeacherList);
                    TopicMessage topicMessageTeacher = new TopicMessage();
                    topicMessageTeacher.setMessage(examForDb.getExamName() + "已经正式开始！");
                    topicMessageTeacher.setKey(keyTeacher);
                    //向 TOPIC_TEACHER频道发送消息
                    redisTemplate.convertAndSend("TOPIC_TEACHER", SecurityUtil.getTopicMessage(topicMessageTeacher));
                }
            }

        } else {
            log.error("redis存放正在准备中的考试集合获取出现异常" + str);
        }
    }
}
